/**
  ******************************************************************************
  * @file           : communicate_task.h
  * @author         : Tessia
  * @brief          : None
  * @attention      : None
  * @date           : 2024/2/15
  ******************************************************************************
  */



#ifndef SENTRY_LEFT_GIMBAL_COMMUNICATE_TASK_H
#define SENTRY_LEFT_GIMBAL_COMMUNICATE_TASK_H

#include "CAN_bsp.h"
#include "drv_dr16.h"
#include "cmsis_os.h"
#include "main.h"
#include "driver_vision.h"
#include "pose_task.h"
#include "driver_vision.h"
#include "bsp_dwt.h"
#include "vision_task.h"

#define DEBUG_VISION_TRANS 0

enum game_stage{
    match_not_start = 0,
    ready_stage,
    self_check,
    countdown_stage,
    during_the_match,
    match_settlement
};

#pragma pack(1)
typedef struct {
    uint16_t ch0: 11;//keil中不兼容，待看
    uint16_t ch1: 11;
    uint16_t ch2: 11;
    uint16_t ch3: 11;
    uint8_t s1: 2;
    uint8_t s2: 2;
    uint8_t is_lost: 1;
    uint8_t reverse_0: 7;
    uint8_t reverse_1: 8;
} rc_info;
#pragma pack()

#pragma pack(1)
typedef struct {
    float yaw_angle;
    uint8_t is_flip_over: 1;
    uint8_t reverse_0: 7;
    uint8_t reverse_1: 8;
    uint8_t reverse_2: 8;
    uint8_t reverse_3: 8;
} chassis_info_tran;
#pragma pack()

typedef struct {
    float yaw_angle;
    uint8_t is_flip_over;
} chassis_info;

#pragma pack(1)
typedef struct {
    uint16_t current_HP;                //当前血量
    uint16_t shooter_barrel_cooling_value;    //机器人枪口每秒冷却值
    /*game_progress
0 ：未开始比赛
1 ：准备阶段
2 ：自检阶段
3 ： 5s 倒计时
4 ：对战中
5 ：比赛结算中*/
    uint8_t  game_progress: 4;      //当前比赛阶段
    uint16_t stage_remain_time;     //当前阶段剩余时间，单位s
    /* bit 0-3 ：
      当血量变化类型为装甲伤害，代表装甲 ID ，
      其中数值为 0-4 号代表机器人的五个装甲片，
      其他血量变化类型，该变量数值为 0 */
    uint8_t be_hit: 1;              //是否受击
    uint8_t hurt_armor_id: 4;
    /*hurt_type
     *     bit 4-7 ：血量变化类型
     *     0x0 装甲伤害扣血
     *     0x1 模块掉线扣血
     *     0x2 超射速扣血
     *     0x3 超枪口热量扣血
     *     0x4 超底盘功率扣血
     *     0x5 装甲撞击扣血
     */
    uint8_t mains_power_shooter_output : 1;     //1 为有 24V 输出， 0 为无 24v 输出

    uint8_t is_occupy_patrol_zone: 1;      //是否占领巡逻区
    uint8_t is_occupy_healing_spot: 1;     //是否占领补血点

    uint8_t HP_deduction_reason: 4;
} judge_info_0_tran;
#pragma pack()


typedef struct {
    uint16_t last_HP;                   //上次血量
    uint16_t current_HP;                //当前血量
    uint16_t shooter_barrel_cooling_value;    //机器人枪口每秒冷却值
    uint8_t  game_progress;      //当前比赛阶段
    /*game_progress
0 ：未开始比赛
1 ：准备阶段
2 ：自检阶段
3 ： 5s 倒计时
4 ：对战中
5 ：比赛结算中*/
    uint16_t stage_remain_time;     //当前阶段剩余时间，单位s
    /* bit 0-3 ：
      当血量变化类型为装甲伤害，代表装甲 ID ，
      其中数值为 0-4 号代表机器人的五个装甲片，
      其他血量变化类型，该变量数值为 0 */
    uint8_t be_hit;              //是否受击
    uint8_t hurt_armor_id;
    /*hurt_type
     *     bit 4-7 ：血量变化类型
     *     0x0 装甲伤害扣血
     *     0x1 模块掉线扣血
     *     0x2 超射速扣血
     *     0x3 超枪口热量扣血
     *     0x4 超底盘功率扣血
     *     0x5 装甲撞击扣血
     */
    uint8_t mains_power_shooter_output;     //1 为有 24V 输出， 0 为无 24v 输出
    uint8_t HP_deduction_reason;

    uint8_t is_occupy_patrol_zone;      //是否占领巡逻区
    uint8_t is_occupy_healing_spot;     //是否占领补血点
} judge_info_0;

#pragma pack(1)
typedef struct {
    uint8_t is_blue: 1;
    uint16_t shooter_barrel_heat_limit;    //机器人1号枪口热量上限
    uint16_t maximum_HP;                   //血量上限

    /*game_type
1 ：RoboMaster 机甲大师赛
2 ：RoboMaster 机甲大师单项赛
3 ：ICRA RoboMaster 人工智能挑战赛
4 ：RoboMaster 联盟赛 3V3
5 ：RoboMaster 联盟赛 1V1*/
    uint8_t  game_type: 4;
    uint16_t remaining_gold_coin;          //剩余金币
    uint64_t reverse: 11;
} judge_info_1_tran;
#pragma pack()


typedef struct {
    uint8_t is_blue;
    uint16_t shooter_barrel_heat_limit;    //机器人1号枪口热量上限
    uint16_t maximum_HP;                   //血量上限

    /*game_type
1 ：RoboMaster 机甲大师赛
2 ：RoboMaster 机甲大师单项赛
3 ：ICRA RoboMaster 人工智能挑战赛
4 ：RoboMaster 联盟赛 3V3
5 ：RoboMaster 联盟赛 1V1*/
    uint8_t  game_type;
    uint16_t remaining_gold_coin;          //剩余金币
} judge_info_1;

#pragma pack(1)
typedef struct {
    uint16_t projectile_allowance_17mm;    //允许发弹量
    uint8_t shooter_id;  //发射机构ID
    float bullet_speed;  //弹丸初速度
    uint64_t reverse: 8;
} judge_info_2_tran;
#pragma pack()

typedef struct {
    uint16_t projectile_allowance_17mm;    //允许发弹量
    uint8_t shooter_id;  //发射机构ID
    float bullet_speed;  //弹丸初速度
} judge_info_2;

#pragma pack(1)
typedef struct {
    uint16_t shooter_17mm_1_barrel_heat; //第1个17mm发射机构的枪口热量
    uint16_t shooter_17mm_2_barrel_heat;
    uint32_t reverse;
} judge_info_3_tran;
#pragma pack()

typedef struct {
    uint16_t shooter_17mm_barrel_heat;
} judge_info_3;

#pragma pack(1)
typedef struct {
    uint8_t frame_header;      //帧头 0x30
    uint8_t is_target_detected;//是否看见敌人
    uint8_t auto_aim;          //是否开启自瞄
    uint8_t is_left_of_axis;   //是否在中轴线左侧
    uint8_t go_attack_outpost; //击打前哨站标志位
    uint8_t is_radar_connect;  //是否与雷达建立通信
    uint8_t camera_0_data;     //小摄像头0的数据


    float twins_pitch;         //计算出来左头的需达到的pitch
    float twins_yaw;           //计算出来左头的需达到的yaw
    float radar_total_yaw;     //雷达yaw

    uint8_t hero_aim_permit;
    uint8_t engineer_aim_permit;
    uint8_t infantry_3_aim_permit;
    uint8_t infantry_4_aim_permit;
    uint8_t infantry_5_aim_permit;
    uint8_t sentry_aim_permit;
    uint8_t base_aim_permit;
    uint8_t outpost_aim_permit;

    uint8_t frame_tail;        //帧尾 0x31
} twins_receive_info_tran;
#pragma pack()

typedef struct {
    uint8_t is_target_detected;//是否看见敌人
    uint8_t auto_aim;          //是否开启自瞄
    uint8_t is_left_of_axis;   //是否在中轴线左侧
    uint8_t go_attack_outpost; //击打前哨站标志位
    uint8_t is_radar_connect;  //是否与雷达建立通信
    uint8_t camera_0_data;     //小摄像头0的数据


    float twins_pitch;         //计算出来左头的需达到的pitch
    float twins_yaw;           //计算出来左头的需达到的yaw
    float radar_total_yaw;     //雷达yaw

    uint8_t hero_aim_permit;
    uint8_t engineer_aim_permit;
    uint8_t infantry_3_aim_permit;
    uint8_t infantry_4_aim_permit;
    uint8_t infantry_5_aim_permit;
    uint8_t sentry_aim_permit;
    uint8_t base_aim_permit;
    uint8_t outpost_aim_permit;

} twins_receive_info;

#pragma pack(1)
typedef struct {
    uint8_t frame_header;         //帧头 0x30
    uint8_t is_target_detected;   //是否看见敌人
    uint8_t armor_number_last;    //最近一次装甲板编号
    uint8_t is_right_of_axis;     //是否在中轴线右侧
    uint8_t is_chassis_yaw_stop;  //大yaw停止转动
    float twins_pitch;            //计算出来右头需达到的的pitch
    float twins_yaw;              //计算出来右头需达到的yaw
    float chassis_cal_yaw;        //左头计算出来底盘的yaw
    float current_left_yaw;       //左头当前yaw
    uint8_t frame_tail;           //帧尾 0x31

} twins_tran_info;
#pragma pack()

enum enemy_num{
    hero = 1,
    engineer = 2,
    infantry_3 = 3,
    infantry_4 = 4,
    infantry_5 = 5,
    sentry = 7,
    base = 10,          //基地
    outpost = 11,       //前哨站
};

#ifdef __cplusplus
extern "C" {
#endif
//C
void communicate_can_task(void *argument);
void communicate_usb_receive_task(void *argument);
void communicate_usb_transmit_task(void *argument);
void communicate_uart_vision_task(void *argument);
void communicate_uart_twins_task(void *argument);
void communicate_mini_camera_receive_task(void *argument);

#ifdef __cplusplus
}
#endif
//C++

#endif //SENTRY_LEFT_GIMBAL_COMMUNICATE_TASK_H
